﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GBPVR.Public;
using System.Drawing;
using GBPVRX2;
using System.Xml;
using GBPVRLibrary.UtilityLibrary;

namespace GBPVRLibrary.ControlLibrary
{
    public class Marquee:GuiElement
    {
        private GBPVRUiElementNonAnimating Texture1 { get; set; }
        private GBPVRUiElementNonAnimating Texture2 { get; set; }
        /// <summary>
        /// The text used in the current textures
        /// </summary>
        private string TextureText { get; set; }
        /// <summary>
        /// Gets or sets the text to be displayed in the Marquee
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// The skinfont the Marquee will use to render
        /// </summary>
        public SkinFont Font { get; set; }
        /// <summary>
        /// The starting right point of x 
        /// </summary>
        private float StartPointX { get; set; }

        /// <summary>
        /// The percent of the total text displayable in the Marquee bounds
        /// </summary>
        private float PercentDisplayable { get; set; }
        /// <summary>
        /// The size in pixels the Marquee takes up
        /// </summary>
        private Size SizeInPixels { get; set; }

        public Marquee(SkinHelper2 SkinHelper, XmlNode PlacementNode)
        {
            Font = new SkinFont() { Brush = SkinHelper.getNamedFontBrush(PlacementNode.Attributes["textStyle"].Value), Font = SkinHelper.getNamedFont(PlacementNode.Attributes["textStyle"].Value) };

            this.Location = SkinHelper.getPlacementRect(PlacementNode.Attributes["name"].Value);
        }

        private DateTime LastScrollTime = DateTime.MinValue;
        private int ScrollInterval = 200; // milliseconds
        private float ScrollAmount { get; set; }

        protected override void Render(System.Collections.ArrayList RenderList, ref bool RequiresMoreRendering)
        {
            if (String.IsNullOrEmpty(Text))
                return;
            if (Texture1 == null || TextureText != Text)
            {
                SizeInPixels = new Size
                               (
                                    (int)(this.Location.Width * SkinHelper.getCurrentScreenSize().Width / 100),
                                    (int)(this.Location.Height * SkinHelper.getCurrentScreenSize().Height / 100)
                               );
                SizeF size = Font.MeasureString(this.Text + " | ", null);

                // render the text to a Image
                Image img = new Bitmap((int)Math.Round(size.Width + 0.5, 0), (int)Math.Round(SizeInPixels.Height + 0.5, 0));
                Font.Render(img, new Rectangle(0, 0, img.Width, img.Height), this.Text + " | ");
                if (Texture1 != null)
                {
                    PluginHelper.DisposeResource(Texture1);
                    Texture1 = null;
                }
                if (Texture2 != null)
                {
                    PluginHelper.DisposeResource(Texture2);
                    Texture2 = null;
                }
                Texture1 = new GBPVRUiElementNonAnimating("MarqueeText1", Location, img);
                Texture2 = new GBPVRUiElementNonAnimating("MarqueeText2", Location, img);
                this.TextureText = Text;
                ScrollAmount = 0.005f;
                this.PercentDisplayable = SizeInPixels.Width / size.Width;

                if (size.Height < SizeInPixels.Height)
                {
                    //ScrollAmount = 0f;
                    StartPointX = 1f * PercentDisplayable;
                    Texture1.textureTopRight.X = StartPointX;
                    Texture1.textureBottomRight.X = StartPointX;

                    PointF temp = GetEndLocation(Texture1);
                    Texture2.textureTopLeft.X = -(1f - StartPointX);// temp.X;
                    Texture2.textureBottomLeft.X = -(1f - StartPointX);//temp.X;
                    Texture2.textureTopRight.X = -(1f - StartPointX) + StartPointX; //temp.Y;
                    Texture2.textureBottomRight.X = -(1f - StartPointX) + StartPointX;// temp.Y;
                }
                else
                {
                }
                LastScrollTime = DateTime.Now.AddSeconds(3); // make it pause for a bit
            }
            if (LastScrollTime < DateTime.Now.AddMilliseconds(-ScrollInterval))               
            {
                Texture1.textureTopLeft.X += ScrollAmount;
                Texture1.textureBottomLeft.X += ScrollAmount;
                Texture1.textureTopRight.X += ScrollAmount;
                Texture1.textureBottomRight.X += ScrollAmount;
                Texture2.textureTopLeft.X += ScrollAmount;
                Texture2.textureBottomLeft.X += ScrollAmount;
                Texture2.textureTopRight.X += ScrollAmount;
                Texture2.textureBottomRight.X += ScrollAmount;
                LastScrollTime = DateTime.Now;
            }
            RenderList.Add(Texture1);
            RenderList.Add(Texture2);
            GuiElement.NeedsRendering = true;
        }

        private PointF GetEndLocation(GBPVRUiElement Texture)
        {
            PointF p = new PointF();
            p.X = Texture.textureBottomRight.X;
            p.Y = p.X + (Texture.textureBottomRight.X - Texture.textureBottomLeft.X);
            return p;
        }

        public new bool NeedsRendering
        {
            get
            {
                return (LastScrollTime < DateTime.Now.AddMilliseconds(-ScrollInterval));
            }
        }

        public override void Dispose()
        {
            if (Texture1 != null)
                PluginHelper.DisposeResource(Texture1);
            Texture1 = null;
            if (Texture2 != null)
                PluginHelper.DisposeResource(Texture2);
            Texture2 = null;
            //if (Font != null)
            //    Font.Dispose();
            //Font = null;
            Text = null;
            this.TextureText = null;
        }
    }
}
